package com.buanalintas.sandals.pos.receipt;

import com.buanalintas.bynga.Action;
import com.buanalintas.bynga.Controller;
import com.buanalintas.bynga.Dictionary;
import com.buanalintas.bynga.Field;
import com.buanalintas.bynga.Logger;
import com.buanalintas.bynga.Page;
import com.buanalintas.bynga.Persistence;
import com.buanalintas.bynga.Sequence;
import com.buanalintas.bynga.Utility;
import com.buanalintas.bynga.formatter.DateFormatter;
import com.buanalintas.bynga.formatter.MoneyFormatter;
import com.buanalintas.sandals.pos.entities.PosMasterItemStock;
import com.buanalintas.sandals.pos.entities.PosMasterStatus;
import com.buanalintas.sandals.pos.entities.PosTransactionBarcode;
import com.buanalintas.sandals.pos.entities.PosTransactionItemStock;
import com.buanalintas.sandals.pos.entities.PosTransactionPurchaseOrder;
import com.buanalintas.sandals.pos.entities.PosTransactionPurchaseOrderDetail;
import com.buanalintas.sandals.pos.entities.PosTransactionReceipt;
import com.buanalintas.sandals.pos.entities.PosTransactionReceiptDetail;
import com.buanalintas.sandals.pos.item.Item;
import com.buanalintas.sandals.pos.receiptdetail.ReceiptDetail;
import com.buanalintas.sandals.pos.status.Status;
import java.math.BigDecimal;
import java.util.Calendar;
import java.util.List;
import javax.persistence.EntityManager;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public class Receipt extends Page {

    private Field receiptId;
    private Field receiptNumber;
    private Field receiptUnitId;
    private Field receiptUserId;
    private Field receiptPurchaseOrderId;
    private Field receiptPurchaseOrderTotalQuantity;
    private Field receiptPurchaseOrderReceived;
    private Field receiptPurchaseOrderAdd;
    private Field receiptReturQuantity;
    private Field receiptPurchaseOrderProgress;
    private Field receiptDate;
    private Field receiptTotal;
    private Field receiptPaid;
    private Field receiptKeel;
    private Field receiptTimestamp;
    private Field receiptDescription;

    public Receipt() {
        super();
        setTheClass(PosTransactionReceipt.class);
        setPageDetail(ReceiptDetail.class);

        receiptId = new Field();
        receiptId.setName("receiptId");
        receiptId.setCaption("id");
        receiptId.setListProperties("");
        receiptId.setInputProperties("");
        getFields().add(receiptId);

        receiptNumber = new Field();
        receiptNumber.setName("receiptNumber");
        receiptNumber.setCaption("number");
        receiptNumber.setListProperties(" align=\"center\" width=\"15%\" nowrap");
        receiptNumber.setInputProperties(" size=\"20\" readonly");
        receiptNumber.setRequired(true);
        getFields().add(receiptNumber);

        receiptUnitId = new Field();
        receiptUnitId.setName("receiptUnitId");
        receiptUnitId.setCaption("unit");
        receiptUnitId.setListProperties(" align=\"center\" width=\"15%\" nowrap");
        receiptUnitId.setInputProperties("");
        getFields().add(receiptUnitId);

        receiptUserId = new Field();
        receiptUserId.setName("receiptUserId");
        receiptUserId.setCaption("user");
        receiptUserId.setListProperties(" align=\"center\" width=\"15%\" nowrap");
        receiptUserId.setInputProperties("");
        getFields().add(receiptUserId);

        receiptPurchaseOrderId = new Field();
        receiptPurchaseOrderId.setName("receiptPurchaseOrderId");
        receiptPurchaseOrderId.setCaption("purchase order");
        receiptPurchaseOrderId.setListProperties(" align=\"center\" width=\"15%\" nowrap");
        receiptPurchaseOrderId.setInputProperties(" size=\"20\" readonly");
        receiptPurchaseOrderId.setRequired(true);
        receiptPurchaseOrderId.setSelectorLoad(true);
        receiptPurchaseOrderId.setSelectorCondition("t.purchaseOrderProgress='1'");
//        receiptPurchaseOrderId.getSelectorAction().add(new String[]{"value", "receiptPurchaseOrderTotalQuantity", "purchaseOrderTotalQuantity"});
//        receiptPurchaseOrderId.getSelectorAction().add(new String[]{"value", "receiptPurchaseOrderReceived", "purchaseOrderReceived"});
        receiptPurchaseOrderId.getSelectorAction().add(new String[]{"value", "receiptDescription", "purchaseOrderDescription"});
        receiptPurchaseOrderId.getSelectorColumns().add(new String[]{"purchaseOrderNumber", "Number", "width=\"20%\" nowrap"});
        receiptPurchaseOrderId.getSelectorColumns().add(new String[]{"purchaseOrderSupplierId", "Supplier", "width=\"20%\""});
        receiptPurchaseOrderId.getSelectorColumns().add(new String[]{"purchaseOrderTotalQuantity", " Total Quantity", " align=\"right\" width=\"10%\" nowrap"});
        receiptPurchaseOrderId.getSelectorColumns().add(new String[]{"purchaseOrderReceived", " Received", " align=\"right\" width=\"10%\" nowrap"});
        receiptPurchaseOrderId.getSelectorColumns().add(new String[]{"purchaseOrderDescription", " Description", "width=\"40%\""});
        receiptPurchaseOrderId.setSelectorOrder("t.purchaseOrderNumber");
        getFields().add(receiptPurchaseOrderId);

        receiptPurchaseOrderTotalQuantity = new Field();
        receiptPurchaseOrderTotalQuantity.setName("receiptPurchaseOrderTotalQuantity");
        receiptPurchaseOrderTotalQuantity.setCaption("total quantity");
        receiptPurchaseOrderTotalQuantity.setListProperties(" align=\"right\" width=\"8%\" nowrap");
        receiptPurchaseOrderTotalQuantity.setInputProperties(" size=\"8\" readonly");
        getFields().add(receiptPurchaseOrderTotalQuantity);

        receiptDate = new Field();
        receiptDate.setName("receiptDate");
        receiptDate.setCaption("date");
        receiptDate.setListProperties(" align=\"center\" width=\"6%\" nowrap");
        receiptDate.setInputProperties(" size=\"8\" readonly");
        receiptDate.setDefaultValue(Utility.getTimestamp());
        getFields().add(receiptDate);

        receiptPurchaseOrderReceived = new Field();
        receiptPurchaseOrderReceived.setName("receiptPurchaseOrderReceived");
        receiptPurchaseOrderReceived.setCaption("received");
        receiptPurchaseOrderReceived.setListProperties(" align=\"right\" width=\"7%\" nowrap");
        receiptPurchaseOrderReceived.setInputProperties(" size=\"8\" readonly");
        getFields().add(receiptPurchaseOrderReceived);

        receiptPurchaseOrderProgress = new Field();
        receiptPurchaseOrderProgress.setName("receiptPurchaseOrderProgress");
        receiptPurchaseOrderProgress.setCaption("progress");
        receiptPurchaseOrderProgress.setListProperties(" align=\"center\" width=\"5%\" nowrap");
        receiptPurchaseOrderProgress.setInputProperties(" size=\"8\"");
        receiptPurchaseOrderProgress.getOptions().add(new String[]{"1", "NOT ENOUGH"});
        receiptPurchaseOrderProgress.getOptions().add(new String[]{"2", "ENOUGH"});
        getFields().add(receiptPurchaseOrderProgress);

        receiptPurchaseOrderAdd = new Field();
        receiptPurchaseOrderAdd.setName("receiptPurchaseOrderAdd");
        receiptPurchaseOrderAdd.setCaption("add");
        receiptPurchaseOrderAdd.setListProperties(" align=\"right\" width=\"7%\" nowrap");
        receiptPurchaseOrderAdd.setInputProperties(" size=\"8\" ");
        receiptPurchaseOrderAdd.setRequired(true);
        getFields().add(receiptPurchaseOrderAdd);

        receiptReturQuantity = new Field();
        receiptReturQuantity.setName("receiptReturQuantity");
        receiptReturQuantity.setCaption("retur");
        receiptReturQuantity.setListProperties(" align=\"right\" width=\"6%\" nowrap");
        receiptReturQuantity.setInputProperties(" size=\"8\"");
        getFields().add(receiptReturQuantity);

        receiptTotal = new Field();
        receiptTotal.setName("receiptTotal");
        receiptTotal.setCaption("total payment");
        receiptTotal.setListProperties(" align=\"right\" width=\"8%\" nowrap");
        receiptTotal.setInputProperties(" size=\"8\"");
        receiptTotal.setRequired(true);
        receiptTotal.setFormater(MoneyFormatter.getInstance());
        getFields().add(receiptTotal);

        receiptPaid = new Field();
        receiptPaid.setName("receiptPaid");
        receiptPaid.setCaption("paid");
        receiptPaid.setListProperties(" align=\"right\" width=\"8%\" nowrap");
        receiptPaid.setInputProperties(" size=\"8\"");
        receiptPaid.setRequired(true);
        receiptPaid.setFormater(MoneyFormatter.getInstance());
        getFields().add(receiptPaid);

        receiptKeel = new Field();
        receiptKeel.setName("receiptKeel");
        receiptKeel.setCaption("keel");
        receiptKeel.setListProperties(" align=\"center\" width=\"5%\" nowrap");
        receiptKeel.setInputProperties(" ");
        receiptKeel.getOptions().add(new String[]{"1", "NO"});
        receiptKeel.getOptions().add(new String[]{"2", "YES"});
        getFields().add(receiptKeel);

        receiptTimestamp = new Field();
        receiptTimestamp.setName("receiptTimestamp");
        receiptTimestamp.setCaption("timestamp");
        receiptTimestamp.setListProperties(" align=\"center\" width=\"1%\" nowrap");
        receiptTimestamp.setInputProperties(" size=\"12\"");
        getFields().add(receiptTimestamp);

        receiptDescription = new Field();
        receiptDescription.setName("receiptDescription");
        receiptDescription.setCaption("description");
        receiptDescription.setListProperties(" width=\"70%\"");
        receiptDescription.setInputProperties(" cols=\"50\" rows=\"5\"");
        receiptDescription.setInputType(Field.INPUT_TEXT_AREA);
        receiptDescription.setInputCase(Field.CASE_UPPER);
        getFields().add(receiptDescription);

        getActions().add(Action.TRANS_ADD);
        getActions().add(Action.TRANS_EDIT);
        getActions().add(Action.TRANS_VIEW);

        fillFields();

        getFieldsAdd().clear();
        getFieldsAdd().add(receiptNumber);
        getFieldsAdd().add(receiptPurchaseOrderId);
        getFieldsAdd().add(receiptDate);
//        getFieldsAdd().add(receiptPurchaseOrderTotalQuantity);
//        getFieldsAdd().add(receiptPurchaseOrderReceived);
//        getFieldsAdd().add(receiptPurchaseOrderAdd);ss
//        getFieldsAdd().add(receiptReturQuantity);
        getFieldsAdd().add(receiptDescription);

        getFieldsEdit().clear();
        getFieldsEdit().add(receiptNumber);
        getFieldsEdit().add(receiptPurchaseOrderId);
//        getFieldsEdit().add(receiptPurchaseOrderTotalQuantity);
//        getFieldsEdit().add(receiptPurchaseOrderReceived);
//        getFieldsEdit().add(receiptPurchaseOrderAdd);
//        getFieldsEdit().add(receiptReturQuantity);
        getFieldsEdit().add(receiptDate);
        getFieldsEdit().add(receiptDescription);

        getFieldsList().clear();
        getFieldsList().add(receiptNumber);
        getFieldsList().add(receiptPurchaseOrderId);
        getFieldsList().add(receiptDate);
        getFieldsList().add(receiptPurchaseOrderTotalQuantity);
//        getFieldsList().add(receiptPurchaseOrderAdd);
//        getFieldsList().add(receiptPurchaseOrderReceived);
        getFieldsList().add(receiptReturQuantity);
        getFieldsList().add(receiptTotal);
        getFieldsList().add(receiptPaid);
        getFieldsList().add(receiptKeel);
        getFieldsList().add(receiptDescription);

        getFieldsView().clear();
        getFieldsView().add(receiptDate);
        getFieldsView().add(receiptNumber);
        getFieldsView().add(receiptPurchaseOrderTotalQuantity);
//        getFieldsView().add(receiptPurchaseOrderReceived);
//        getFieldsView().add(receiptPurchaseOrderAdd);
        getFieldsView().add(receiptReturQuantity);
        getFieldsView().add(receiptPurchaseOrderProgress);
        getFieldsView().add(receiptTotal);
        getFieldsView().add(receiptPaid);
        getFieldsView().add(receiptKeel);
        getFieldsView().add(receiptDescription);
        getFieldsView().add(receiptPurchaseOrderId);
        getFieldsView().add(receiptTimestamp);

        setController(new Receipt.ReceiptController(this));
        getController().setOrder(receiptTimestamp);
        getController().setOrderType(Controller.ORDER_DESC);

        setExportList(getClass().getResourceAsStream("ReceiptList.jasper"));
        setExport(getClass().getResourceAsStream("Receipt.jasper"));
    }

//    @Override
//    public String validate(Object data) {
//        HttpSession session = getRequest().getSession();
//        EntityManager em = getEntityManager();
//        PosTransactionReceipt receipt = (PosTransactionReceipt) data;
//        Integer remaining = receipt.getReceiptPurchaseOrderId().getPurchaseOrderTotalQuantity() - (receipt.getReceiptPurchaseOrderId().getPurchaseOrderReceived());
//        if (receipt.getReceiptPurchaseOrderAdd().compareTo(remaining) > 0) {
//            return receipt.getReceiptPurchaseOrderId() + " " + Dictionary.getValue(this, "Too much add") + ", " + Dictionary.getValue(this, "total quantity maximum receipt") + ": " + remaining + " " + Dictionary.getValue(this, "item you add now") + ": " + receipt.getReceiptPurchaseOrderAdd();
//        }
//        return null;
//    }
    @Override
    public void afterInit(HttpServletRequest req, HttpServletResponse res) {
        receiptDate.setFormater(DateFormatter.getInstanceDate(this));
        receiptTimestamp.setFormater(DateFormatter.getInstanceDateTime(this));
    }

    @Override
    public void beforeAdd() {
        receiptNumber.setDefaultValue(generate());
    }

    class ReceiptController extends Controller {

        public ReceiptController(Page page) {
            super(page);
            setOrder(receiptTimestamp);
            setOrderType("DESC");
        }

        @Override
        public void beforeInsert(Object data, List list) {
            PosTransactionReceipt receipt = (PosTransactionReceipt) data;
            receipt.setReceiptNumber(generate());
            receipt.setReceiptUserId(getCurrentUser());
            receipt.setReceiptUnitId(getCurrentUnit());
            receipt.setReceiptTimestamp(Utility.getTimestamp());
            receipt.setReceiptKeel("1");
            receipt.setReceiptReturQuantity(0);
            receipt.setReceiptPaid(BigDecimal.ZERO);

//            for (int i = list.size() - 1; i > 0; i--) {
//                PosTransactionReceiptDetail d1 = (PosTransactionReceiptDetail) list.get(i);
//                for (int j = 0; j < i; j++) {
//                    PosTransactionReceiptDetail d2 = (PosTransactionReceiptDetail) list.get(j);
//                    if (d2.getReceiptDetailItemId().equals(d1.getReceiptDetailItemId())) {
//                        d2.setReceiptDetailQuantity(d2.getReceiptDetailQuantity()+d1.getReceiptDetailQuantity());
//                        list.remove(i);
//                        break;
//                    }
//                }
//            }

        }

        @Override
        public void afterInsert(Object data, List list) {
            EntityManager em = getEntityManager();
            PosMasterStatus statusGood = Status.getStatusGood(em);
            try {
                em.getTransaction().begin();
                PosTransactionReceipt receipt = (PosTransactionReceipt) data;
                PosTransactionPurchaseOrder po = receipt.getReceiptPurchaseOrderId();
                BigDecimal total = BigDecimal.ZERO;
                int qty = 0;

                for (Object detail : list) {
                    PosTransactionReceiptDetail receiptDetail = (PosTransactionReceiptDetail) detail;

                    PosTransactionPurchaseOrderDetail poDetail = (PosTransactionPurchaseOrderDetail) em.createQuery("SELECT t FROM PosTransactionPurchaseOrderDetail t "
                            + "WHERE t.purchaseOrderDetailPurchaseOrderId.purchaseOrderId="
                            + receipt.getReceiptPurchaseOrderId().getPurchaseOrderId()
                            + " AND t.purchaseOrderDetailItemId.itemId ="
                            + receiptDetail.getReceiptDetailItemId().getItemId()
                            + " AND t.purchaseOrderDetailSizeId.sizeId="
                            + receiptDetail.getReceiptDetailSizeId().getSizeId()).
                            setHint(Persistence.REFRESH_HINT, true).getSingleResult();
                    System.out.println("Po --->" + poDetail);
                    poDetail.setPurchaseOrderDetailSent(poDetail.getPurchaseOrderDetailSent() + (receiptDetail.getReceiptDetailQuantity()));
                    poDetail.setPurchaseOrderDetailUnsent(poDetail.getPurchaseOrderDetailUnsent() - (receiptDetail.getReceiptDetailQuantity()));

                    for (int i = 0; i < receiptDetail.getReceiptDetailQuantity(); i++) {
                        PosTransactionBarcode barcode = new PosTransactionBarcode();
                        System.out.println("Barcode :" + barcode);
                        barcode.setBarcodeId(Sequence.next(barcode));
                        barcode.setBarcodeQuantity(1);
                        barcode.setBarcodeBarcode(receiptDetail.getReceiptDetailItemId().getItemBarcode());
                        barcode.setBarcodeInformation(receiptDetail.getReceiptDetailItemId().getItemModel());
                        System.out.println("Barcodee :" + barcode.getBarcodeId());
                        em.persist(barcode);

                    }

                    PosMasterItemStock stock = Item.getStock(em, receiptDetail.getReceiptDetailItemId(), receipt.getReceiptUnitId(), statusGood, receiptDetail.getReceiptDetailItemId().getItemColorId(), receiptDetail.getReceiptDetailSizeId());
                    PosTransactionItemStock itemStock = new PosTransactionItemStock();
                    itemStock.setItemStockId(Sequence.next(itemStock));
                    itemStock.setItemStockItemId(receiptDetail.getReceiptDetailItemId());
                    itemStock.setItemStockSizeId(receiptDetail.getReceiptDetailSizeId());
                    itemStock.setItemStockColorId(receiptDetail.getReceiptDetailItemId().getItemColorId());
                    itemStock.setItemStockUnitId(receipt.getReceiptUnitId());
                    itemStock.setItemStockStatusId(statusGood);
                    itemStock.setItemStockType("2");
                    itemStock.setItemStockLast(stock.getItemStockValue());
                    itemStock.setItemStockValue(receiptDetail.getReceiptDetailQuantity());
                    itemStock.setItemStockCurrent(itemStock.getItemStockLast() + itemStock.getItemStockValue());
                    itemStock.setItemStockUserId(page.getCurrentUser());
                    itemStock.setItemStockTimestamp(Utility.getTimestamp());
                    em.persist(itemStock);

                    BigDecimal priceOld = stock.getItemStockItemId().getItemPriceBasic().multiply(new BigDecimal(stock.getItemStockValue()));
                    BigDecimal priceNew = receiptDetail.getReceiptDetailPrice().multiply(new BigDecimal(receiptDetail.getReceiptDetailQuantity()));
                    BigDecimal oldStockNewStock = new BigDecimal(stock.getItemStockValue() + receiptDetail.getReceiptDetailQuantity());
                    BigDecimal priceRate = priceOld.add(priceNew).divide(oldStockNewStock);
                    stock.getItemStockItemId().setItemPriceBasic(priceRate);
                    stock.setItemStockValue(itemStock.getItemStockCurrent());
                    total = total.add(receiptDetail.getReceiptDetailPrice().multiply(new BigDecimal(receiptDetail.getReceiptDetailQuantity())));
//                    total = total.add(receiptDetail.getReceiptDetailPrice().multiply(new BigDecimal(receipt.getReceiptPurchaseOrderAdd())));
                    qty = qty + receiptDetail.getReceiptDetailQuantity();
                }
                receipt.setReceiptTotal(total);
                System.out.println("total :" + total);
                receipt.setReceiptPurchaseOrderTotalQuantity(qty);
                po.setPurchaseOrderReceived(po.getPurchaseOrderReceived() + qty);
                po.setPurchaseOrderUnreceived(po.getPurchaseOrderUnreceived() - qty);
                if (receipt.getReceiptPurchaseOrderId().getPurchaseOrderReceived() == qty) {
                    receipt.getReceiptPurchaseOrderId().setPurchaseOrderProgress("2");
                    System.out.println("Cekk :" + receipt.getReceiptPurchaseOrderId().getPurchaseOrderProgress());
                    receipt.getReceiptPurchaseOrderId().setPurchaseOrderStatus("2");
                }

                em.getTransaction().commit();
            } catch (Exception e) {
                Logger.getInstance().log(e);
                System.out.println("C :" + e);
            }
        }
    }

    public String generate() {
        String unitCode = (getCurrentUnit()).getUnitCode();
        Calendar cal = Calendar.getInstance();
        String year = "" + cal.get(Calendar.YEAR);
        String month = Utility.intToRoman(cal.get(Calendar.MONTH) + 1);
        try {
            PosTransactionReceipt receipt = (PosTransactionReceipt) getEntityManager().createQuery("SELECT t FROM PosTransactionReceipt t WHERE t.receiptNumber LIKE '%/" + unitCode + "/REC/%/" + year + "' ORDER BY t.receiptTimestamp DESC").setHint(Persistence.REFRESH_HINT, true).setFirstResult(0).setMaxResults(1).getSingleResult();
            return Utility.lpad(Integer.parseInt(receipt.getReceiptNumber().substring(0, 4)) + 1, 4, "0") + "/" + unitCode + "/REC/" + month + "/" + year;
        } catch (Exception e) {
        }
        return "0001/" + unitCode + "/REC/" + month + "/" + year;
    }

    @Override
    public void beforeExport() {
        getExportParams().put("title", Dictionary.getValue(this, "Receipt"));
    }

    @Override
    public void beforeExportMulti() {
        beforeExport();
    }
}